package org.osflash.signals.natives;

import asunit.asserts.*;
import asunit.framework.IAsync;
import org.osflash.signals.IPrioritySignal;
import flash.display.Sprite;
import flash.events.MouseEvent;

class NativeMappedSignalBoundaryUseTest {

	@:meta(Inject())
	public var async : IAsync;
	var signalArrayOfFunctions : NativeMappedSignal;
	var signalPassArray : NativeMappedSignal;
	var signalPassArrayThroughFunction : NativeMappedSignal;
	var sprite : Sprite;
	var EventType : String;
	var func1 : Dynamic;
	var func2 : Dynamic;
	var MappedArray : Array<Dynamic>;
	@:meta(Before())
	public function setUp() : Void {
		sprite = new Sprite();
		signalArrayOfFunctions = new NativeMappedSignal(sprite, EventType).mapTo(func1, func2);
		signalPassArray = new NativeMappedSignal(sprite, EventType).mapTo(MappedArray);
		signalPassArrayThroughFunction = new NativeMappedSignal(sprite, EventType, MouseEvent, Array).mapTo(function() : Array<Dynamic> {
			return MappedArray;
		}
);
	}

	@:meta(After())
	public function tearDown() : Void {
		signalArrayOfFunctions.removeAll();
		signalArrayOfFunctions = null;
		signalPassArray.removeAll();
		signalPassArray = null;
		signalPassArrayThroughFunction.removeAll();
		signalPassArrayThroughFunction = null;
	}

	@:meta(Test())
	public function testInstantiated() : Void {
		assertFalse("sprite has no click event listener to start", sprite.hasEventListener(EventType));
		assertTrue("NativeMappedSignal instantiated", Std.is(signalArrayOfFunctions, NativeMappedSignal));
		assertTrue("implements ISignal", Std.is(signalArrayOfFunctions, IPrioritySignal));
		assertSame("has no value classes", 0, signalArrayOfFunctions.valueClasses.length);
		assertTrue("NativeMappedSignal instantiated", Std.is(signalPassArray, NativeMappedSignal));
		assertTrue("implements IPrioritySignal", Std.is(signalPassArray, IPrioritySignal));
		assertSame("has no value classed", 0, signalPassArray.valueClasses.length);
		assertTrue("NativeMappedSignal instantiated", Std.is(signalPassArrayThroughFunction, NativeMappedSignal));
		assertTrue("implements IPrioritySignal", Std.is(signalPassArrayThroughFunction, IPrioritySignal));
		assertSame("has only one value class", 1, signalPassArrayThroughFunction.valueClasses.length);
		assertSame("single value class is of type Array", Array, signalPassArrayThroughFunction.valueClasses[0]);
	}

	//////
	@:meta(Test())
	public function signal_array_of_functions_add_then_callback_called() : Void {
		signalArrayOfFunctions.add(async.add(callbackTwoFunctions, 10));
		sprite.dispatchEvent(new MouseEvent(EventType));
	}

	function callbackTwoFunctions(argFunc1 : Dynamic, argFunc2 : Dynamic) : Void {
		assertSame(func1, argFunc1);
		assertSame(func2, argFunc2);
	}

	@:meta(Test())
	public function signal_pass_array_add_then_array_callback_should_be_called() : Void {
		signalPassArray.add(async.add(callbackArrayAsArg, 10));
		sprite.dispatchEvent(new MouseEvent(EventType));
	}

	function callbackArrayAsArg(argArray : Array<Dynamic>) : Void {
		assertSame(MappedArray, argArray);
	}

	@:meta(Test())
	public function signal_pass_array_through_function_add_then_array_callback_should_be_called() : Void {
		signalPassArrayThroughFunction.add(async.add(callbackArrayAsArg, 10));
		sprite.dispatchEvent(new MouseEvent(EventType));
	}

}

